#include "widget.h"
#include <QPushButton>
#include <QDebug>

//Teacher 老师类
//Student 学生类
//下课后 老师会触发一个饿了的信号
//学生响应这个信号 并且请老师吃饭


Widget::Widget(QWidget *parent)
    : QWidget(parent)
{
    resize(700, 500);

    this->zt = new Teacher(this);
    this->st = new Student(this);

    //连接信号和槽
    //connect(this->zt, &Teacher::hungry, this->st, &Student::treat);

    //触发信号
    //classIsOver();

    //连接有参信号和槽
    //函数指针 可以指向 函数地址
    //void(Teacher::*teacherSignal)(QString) = &Teacher::hungry;
    //void(Student::*studentSlot)(QString) = &Student::treat;
    //connect(this->zt, teacherSignal, this->st, studentSlot);

    //classIsOver();

    //创建按钮
    /*
    QPushButton * btn = new QPushButton;
    btn->setParent(this);
    btn->setText("下课");
    btn->move(100, 100);

    void(Teacher::*teacherSignal2)() = &Teacher::hungry;
    void(Student::*studentSlot2)() = &Student::treat;
    connect(this->zt, teacherSignal2, this->st, studentSlot2);

    //1.信号是可以连接信号
    connect(btn, &QPushButton::clicked, this->zt, teacherSignal2);

    //关闭窗口
    connect(btn, &QPushButton::clicked, this, &QWidget::close);

    //2.可以断开信号和槽
    //disconnect(this->zt, teacherSignal2, this->st, studentSlot2);

    //3.一个信号可以响应多个槽函数
    //4. 多个信号可以连接同一个槽函数
    //5. 信号和槽函数的参数类型，必须一一对应, 信号的参数个数可以多于槽函数的参数个数，反之不可以, 参数类型要一一对应

    //QT4版本信号和槽的写法
    //利用QT4版本连接有参信号和槽
    //优势: 参数直观
    //劣势: 参数类型不做类型匹配检测
    //本质: 会把SIGNAL("hungry(int)")和 SLOT("treat(QString)")中的函数转成字符串
    //connect(zt, SIGNAL(hungry(QString)), st, SLOT(treat(QString)));
    //classIsOver();
    */

    //[=]函数体内可以使用lambda所在所用范围内所有可见的局部变量
    //最常用的lambda使用[=](){}
    /*
    QPushButton* btn2 = new QPushButton("aaaaa", this);
    [=](){
        btn2->setText("bbbb");
    }();
    */


    QPushButton* btn4 = new QPushButton("关闭窗口", this);
    btn4->move(100, 0);

    //lambda的使用需要在.pro文件中加入CONFIG += c++11支持C++11即可
    //使用&引用时,当进行信号和槽连接时候，空间内部会进入一个锁的状态
    connect(btn4, &QPushButton::clicked, this, [=](){
        qDebug() << "hello";
        btn4->setText("www");
    });


    QPushButton * btn5 = new QPushButton("修改m的值", this);
    QPushButton * btn6 = new QPushButton("未修改m的值", this);
    btn5->move(350, 0);
    btn6->move(550, 0);


    int m = 10;
    //加上mutable修饰符后，可以修改按值传递进来的拷贝
    connect(btn5, &QPushButton::clicked, this, [m]()mutable{
        m = 20;
        qDebug()<< "修改m的值等于20, m=" << m;
    });

    connect(btn6, &QPushButton::clicked, this, [=](){
        qDebug()<< "无法修改m的值, m=" << m;
    });

    //->指定返回值类型
    int num = [=]()->int{
        return 1000;
    }();
    qDebug() << "num=" << num;


    //点击按钮，关闭窗口
    //connect(btn4, &QPushButton::clicked, this, [=](){
    //    this->close();
    //    st->treat("宫保鸡丁");
    //});

    //使用lambda表达式，可以不用加this
    connect(btn4, &QPushButton::clicked, [=](){
        this->close();
        st->treat("宫保鸡丁");
    });


}

Widget::~Widget()
{

}

void Widget::classIsOver(){
    //触发自定义信号
    //emit this->zt->hungry();

    //发送有参的自定义信号
    emit this->zt->hungry("面包");

}
